import pygame
import math
import random

class GameObject:
    def __init__(self, x, y, width, height, object_type, color, health=100):
        self.rect = pygame.Rect(x, y, width, height)
        self.type = object_type
        self.color = color
        self.health = health
        self.initial_health = health
        self.destroyed = False
        self.shake_offset = 0
        self.shake_timer = 0
        self.original_pos = (x, y)
        self.rotation = 0
        self.falling = False
        self.fall_speed = 0
        
        # 材质特性
        if object_type == "wood":
            self.damage_factor = 1.2
            self.color_dark = (139, 69, 19)  # 深棕色
            self.break_threshold = 0.3  # 开始显示破损效果的阈值
        elif object_type == "stone":
            self.damage_factor = 0.8
            self.color_dark = (105, 105, 105)  # 深灰色
            self.break_threshold = 0.5
        else:  # glass
            self.damage_factor = 1.5
            self.color_dark = (176, 196, 222)  # 浅蓝灰色
            self.break_threshold = 0.2

    def take_damage(self, damage):
        """处理受到的伤害"""
        old_health = self.health
        self.health -= damage * self.damage_factor
        
        # 启动震动效果
        if self.health > 0:
            self.start_shake()
        
        # 检查是否破坏
        if self.health <= 0 and not self.destroyed:
            self.destroyed = True
            self.falling = True
            return True
        
        # 检查是否达到破损阈值
        if (old_health / self.initial_health > self.break_threshold and 
            self.health / self.initial_health <= self.break_threshold):
            self.start_shake(duration=20)
        
        return False

    def start_shake(self, duration=10, intensity=5):
        """开始震动效果"""
        self.shake_timer = duration
        self.shake_offset = intensity

    def update(self):
        """更新对象状态"""
        # 更新震动效果
        if self.shake_timer > 0:
            self.shake_timer -= 1
            self.rect.x = self.original_pos[0] + random.randint(-self.shake_offset, self.shake_offset)
            self.rect.y = self.original_pos[1] + random.randint(-self.shake_offset, self.shake_offset)
        else:
            self.rect.x = self.original_pos[0]
            self.rect.y = self.original_pos[1]
        
        # 更新下落效果
        if self.falling:
            self.fall_speed += 0.5  # 重力加速度
            self.rect.y += self.fall_speed
            self.rotation += 5  # 旋转效果
            
            # 如果物体落出屏幕，标记为已销毁
            if self.rect.top > 1000:  # 屏幕高度 + 缓冲区
                self.destroyed = True

    def draw(self, screen):
        """绘制对象"""
        if self.destroyed and not self.falling:
            return

        # 创建表面用于旋转
        surface = pygame.Surface((self.rect.width, self.rect.height), pygame.SRCALPHA)
        
        # 计算健康度百分比
        health_percent = self.health / self.initial_health
        
        # 根据损坏程度调整颜色
        if health_percent > self.break_threshold:
            current_color = self.color
        else:
            # 损坏状态下的颜色（更暗）
            current_color = tuple(max(0, c - 50) for c in self.color)
        
        # 绘制主体
        pygame.draw.rect(surface, current_color, 
                        (0, 0, self.rect.width, self.rect.height))
        
        # 添加材质效果
        if self.type == "wood":
            # 木纹效果
            for i in range(3):
                y = (i + 1) * self.rect.height // 4
                pygame.draw.line(surface, self.color_dark,
                               (0, y), (self.rect.width, y), 2)
            # 破损效果
            if health_percent <= self.break_threshold:
                self._draw_cracks(surface)
                
        elif self.type == "stone":
            # 石块纹理
            pygame.draw.rect(surface, self.color_dark,
                           (0, 0, self.rect.width, self.rect.height), 3)
            pygame.draw.line(surface, self.color_dark,
                           (0, self.rect.height/2),
                           (self.rect.width, self.rect.height/2), 2)
            if health_percent <= self.break_threshold:
                self._draw_cracks(surface)
                
        else:  # glass
            # 玻璃反光效果
            pygame.draw.rect(surface, self.color_dark,
                           (0, 0, self.rect.width, self.rect.height), 2)
            pygame.draw.line(surface, (255, 255, 255),
                           (5, 5), (self.rect.width-5, 5), 2)
            if health_percent <= self.break_threshold:
                self._draw_glass_cracks(surface)
        
        # 旋转表面
        if self.falling:
            rotated_surface = pygame.transform.rotate(surface, self.rotation)
            screen.blit(rotated_surface, 
                       (self.rect.x - (rotated_surface.get_width() - self.rect.width) / 2,
                        self.rect.y - (rotated_surface.get_height() - self.rect.height) / 2))
        else:
            screen.blit(surface, self.rect)
        
        # 绘制健康度条（当受损时）
        if health_percent < 1 and health_percent > 0:
            bar_width = self.rect.width
            bar_height = 4
            bar_x = self.rect.x
            bar_y = self.rect.y - 8
            
            # 背景
            pygame.draw.rect(screen, (255, 0, 0),
                           (bar_x, bar_y, bar_width, bar_height))
            # 当前健康度
            pygame.draw.rect(screen, (0, 255, 0),
                           (bar_x, bar_y, bar_width * health_percent, bar_height))

    def _draw_cracks(self, surface):
        """绘制破损纹理"""
        for _ in range(3):
            start_x = random.randint(0, self.rect.width)
            start_y = random.randint(0, self.rect.height)
            points = [(start_x, start_y)]
            
            for _ in range(3):
                prev_x, prev_y = points[-1]
                new_x = prev_x + random.randint(-10, 10)
                new_y = prev_y + random.randint(-10, 10)
                points.append((new_x, new_y))
            
            pygame.draw.lines(surface, self.color_dark, False, points, 2)

    def _draw_glass_cracks(self, surface):
        """绘制玻璃特有的破损纹理"""
        center_x = self.rect.width // 2
        center_y = self.rect.height // 2
        
        for _ in range(6):
            angle = random.uniform(0, 2 * math.pi)
            length = random.randint(10, 20)
            end_x = center_x + math.cos(angle) * length
            end_y = center_y + math.sin(angle) * length
            
            pygame.draw.line(surface, (200, 200, 200),
                           (center_x, center_y), (end_x, end_y), 1)

class Bird:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.radius = 15
        self.color = (255, 0, 0)  # 红色
        self.eye_color = (255, 255, 255)  # 白色
        self.beak_color = (255, 165, 0)  # 橙色
        self.velocity_x = 0
        self.velocity_y = 0
        self.is_flying = False
        self.squash = 1.0  # 形变系数
        self.rotation = 0  # 旋转角度
        self.blink_timer = 0  # 眨眼计时器
        self.expression = "normal"  # 表情状态
        self.trail_counter = 0  # 拖尾计数器
        
        # 物理常量
        self.gravity = 0.5
        self.elasticity = 0.7
        self.drag = 0.99
        
        # 动画常量
        self.BLINK_INTERVAL = 60  # 眨眼间隔
        self.BLINK_DURATION = 5   # 眨眼持续时间
        
        # 表情定义
        self.expressions = {
            "normal": {"eye_scale": 1.0, "beak_offset": 0},
            "determined": {"eye_scale": 0.8, "beak_offset": 2},
            "hit": {"eye_scale": 1.2, "beak_offset": -1},
            "dizzy": {"eye_scale": 0.7, "beak_offset": 0, "spiral_eyes": True}
        }

    def launch(self, start_x, start_y, pull_x, pull_y):
        """发射小鸟"""
        self.x = start_x
        self.y = start_y
        
        dx = start_x - pull_x
        dy = start_y - pull_y
        distance = math.sqrt(dx * dx + dy * dy)
        
        # 改进的力量计算
        base_power = distance * 0.15
        power = min(base_power, 20)
        
        # 添加轻微的随机性
        random_factor = random.uniform(0.95, 1.05)
        
        self.velocity_x = dx * power * random_factor / distance
        self.velocity_y = dy * power * random_factor / distance
        self.is_flying = True
        
        # 重置形变和旋转
        self.squash = 1.0
        self.rotation = math.degrees(math.atan2(dy, dx))
        
        # 设置发射表情
        self.expression = "determined"
        self.trail_counter = 0

    def update(self):
        """更新小鸟状态"""
        if not self.is_flying:
            # 站立时的动画
            self.squash = 1.0 + math.sin(pygame.time.get_ticks() * 0.005) * 0.05
            self.rotation = 0
        else:
            # 飞行时的动画
            self.velocity_y += self.gravity
            self.velocity_x *= self.drag
            self.velocity_y *= self.drag
            
            self.x += self.velocity_x
            self.y += self.velocity_y
            
            # 根据运动方向计算旋转角度
            self.rotation = math.degrees(math.atan2(self.velocity_y, self.velocity_x))
            
            # 根据速度计算形变
            speed = math.sqrt(self.velocity_x ** 2 + self.velocity_y ** 2)
            self.squash = 1.0 + min(speed * 0.02, 0.3)
            
            # 更新拖尾计数器
            self.trail_counter += 1
        
        # 更新眨眼动画
        if self.blink_timer > 0:
            self.blink_timer -= 1
        elif random.random() < 0.005:  # 随机眨眼
            self.blink_timer = self.BLINK_DURATION
        
        # 逐渐恢复正常表情
        if self.expression in ["hit", "determined"] and random.random() < 0.02:
            self.expression = "normal"

    def draw(self, screen):
        """绘制小鸟"""
        # 创建一个临时surface来绘制小鸟
        bird_surface = pygame.Surface((self.radius * 4, self.radius * 4), pygame.SRCALPHA)
        center = (bird_surface.get_width() // 2, bird_surface.get_height() // 2)
        
        # 获取当前表情参数
        expr = self.expressions[self.expression]
        eye_scale = expr.get("eye_scale", 1.0)
        beak_offset = expr.get("beak_offset", 0)
        
        # 计算形变后的半径
        squashed_radius_x = self.radius * self.squash
        squashed_radius_y = self.radius / self.squash
        
        # 绘制身体（椭圆）
        pygame.draw.ellipse(bird_surface, self.color,
                          (center[0] - squashed_radius_x,
                           center[1] - squashed_radius_y,
                           squashed_radius_x * 2,
                           squashed_radius_y * 2))
        
        # 计算眼睛位置
        eye_offset_x = 5 * self.squash
        eye_offset_y = -3 / self.squash
        
        # 绘制眼睛
        if self.blink_timer > 0:
            # 眨眼状态
            pygame.draw.line(bird_surface, (0, 0, 0),
                           (center[0] + eye_offset_x - 3, center[1] + eye_offset_y),
                           (center[0] + eye_offset_x + 3, center[1] + eye_offset_y), 2)
        elif expr.get("spiral_eyes", False):
            # 眩晕效果
            for i in range(3):
                radius = (i + 1) * 2
                angle = pygame.time.get_ticks() * 0.01 + i * math.pi / 2
                spiral_x = center[0] + eye_offset_x + math.cos(angle) * radius
                spiral_y = center[1] + eye_offset_y + math.sin(angle) * radius
                pygame.draw.circle(bird_surface, (0, 0, 0),
                                (int(spiral_x), int(spiral_y)), 1)
        else:
            # 正常眼睛
            eye_radius = 4 * eye_scale
            pygame.draw.circle(bird_surface, self.eye_color,
                            (int(center[0] + eye_offset_x),
                             int(center[1] + eye_offset_y)), int(eye_radius))
            pygame.draw.circle(bird_surface, (0, 0, 0),
                            (int(center[0] + eye_offset_x),
                             int(center[1] + eye_offset_y)), int(eye_radius * 0.5))
        
        # 绘制喙
        beak_points = [
            (center[0] + (12 + beak_offset) * self.squash, center[1]),
            (center[0] + (22 + beak_offset) * self.squash, center[1]),
            (center[0] + (12 + beak_offset) * self.squash, center[1] + 5 / self.squash)
        ]
        pygame.draw.polygon(bird_surface, self.beak_color, beak_points)
        
        # 根据飞行方向旋转小鸟
        if self.is_flying:
            rotated_surface = pygame.transform.rotate(bird_surface, -self.rotation)
        else:
            rotated_surface = bird_surface
        
        # 绘制到屏幕上
        screen.blit(rotated_surface,
                   (self.x - rotated_surface.get_width() // 2,
                    self.y - rotated_surface.get_height() // 2))

    def check_collision(self, game_object):
        """检查与游戏对象的碰撞"""
        closest_x = max(game_object.rect.left,
                       min(self.x, game_object.rect.right))
        closest_y = max(game_object.rect.top,
                       min(self.y, game_object.rect.bottom))
        
        distance_x = self.x - closest_x
        distance_y = self.y - closest_y
        distance = math.sqrt(distance_x * distance_x + distance_y * distance_y)
        
        if distance <= self.radius:
            # 计算碰撞伤害
            impact_speed = math.sqrt(self.velocity_x ** 2 + self.velocity_y ** 2)
            damage = impact_speed * 10
            
            # 碰撞响应
            normal_x = distance_x / distance if distance > 0 else 0
            normal_y = distance_y / distance if distance > 0 else 0
            
            # 计算反弹速度
            dot_product = (self.velocity_x * normal_x + 
                         self.velocity_y * normal_y)
            
            self.velocity_x = self.velocity_x - 2 * dot_product * normal_x
            self.velocity_y = self.velocity_y - 2 * dot_product * normal_y
            
            # 应用能量损失
            self.velocity_x *= self.elasticity
            self.velocity_y *= self.elasticity
            
            # 碰撞形变效果
            self.squash = 1.3
            
            # 设置碰撞表情
            self.expression = "hit"
            
            return damage
        return 0

    def handle_boundary_collision(self, width, height):
        """处理边界碰撞"""
        collision_occurred = False
        
        if self.x - self.radius < 0:
            self.x = self.radius
            self.velocity_x = -self.velocity_x * self.elasticity
            collision_occurred = True
        elif self.x + self.radius > width:
            self.x = width - self.radius
            self.velocity_x = -self.velocity_x * self.elasticity
            collision_occurred = True
        
        if self.y - self.radius < 0:
            self.y = self.radius
            self.velocity_y = -self.velocity_y * self.elasticity
            collision_occurred = True
        elif self.y + self.radius > height:
            self.y = height - self.radius
            self.velocity_y = -self.velocity_y * self.elasticity
            self.velocity_x *= 0.95  # 地面摩擦
            collision_occurred = True
        
        if collision_occurred:
            # 碰撞形变效果
            self.squash = 1.2
            # 设置碰撞表情
            self.expression = "hit"
            
        # 检查是否停止运动
        if (abs(self.velocity_x) < 0.1 and 
            abs(self.velocity_y) < 0.1 and 
            self.y > height - self.radius - 1):
            self.expression = "dizzy"